サンタさんのプレゼント受付窓口のボットを作ってみた – Amazon Connect アドベントカレンダー 2022
こんにちは、洲崎です。
Amazon Connect アドベントカレンダー 2022、24日目の記事です!
クラスメソッドとギークフィードさんの有志が募ってチャレンジしている企画になります。
(アドベントカレンダーのカレンダー一覧はこちら↓)
今日はクリスマスイブということで、サンタさんのプレゼント受付窓口のボットを作ってみました。
実装画面
Amazon Connect Chatを埋め込んだシンプルなWebページです。
チャットで「配達希望日」と「欲しいもの」を伝えます。
チャットが終了したら、Amazon SNSで登録したサンタさんのプレゼント受付窓口宛に「配達希望日」と「欲しいもの」をEメールで連絡する仕組みです。
構成図
Amazon CloudFront × Amazon S3でチャットページを用意します。
裏側はAmazon Lex→AWS Lambda→Amazon SNSでプレゼント受付窓口にEメールで連絡します。
Amazon LexはAWS Lambdaからのreturn値も必要になるため、Lex↔︎Lambda間は交互に指してます。
やってみる
Amazon Lex
Amazon Lexのボットを作成します。
ボットは分かる名前と説明を入力し、IAMロールは自動作成、他はデフォルトです。
インテントでプレゼント窓口のフローを作成します。
インテントは、”サンプル発話”、”スロット”、”Confirmation”、”フルフィルメント”、”応答を閉じる”の箇所を設定します。
サンプル発話
サンプル発話にはトリガーとなる発話をいれます。「プレゼントが欲しい」や「サンタさんにお願いしたい」を入れました。
スロット
チャットで連絡してきた情報をスロットとして保存します。
今回はdelivery
(スロットタイプ:AMAZON.Date)で「いつお届けしますか?」に対する回答と、iwant
(カスタムスロットタイプ:want)で「何が欲しいですか?」の2つを設定しました。
スロットタイプのAMAZON.Dateは組み込みで用意されているのでそのまま利用できます。
AMAZON.Dateは「today」、「now」、または「12月24日」等の連絡を、2022-12-24
として変換する機能です。
今日だけでなく、「来週」や「先週」等も変換可能です。詳しくは下記ドキュメントを参照ください。
カスタムスロットタイプは、組み込みスロットにない情報を保存したい時に使う機能です。別で作成する必要があります。
ボットの”スロットタイプ”から、”スロットタイプを追加”→”空のスロットタイプを追加”でスロットタイプを追加で作成します。
スロットタイプ値のところで、「入力されそうなワード」をいくつか入力します。
今回は「スイッチ」、「カービィのゲーム」、「マリオのゲーム」、「くまのぬいぐるみ」を登録しました。
これ以外の発話だとLexが認識しない為、事前にリサーチして入力しそうな単語を入れるようにします。
(Lexはフリーワードをスロットとして登録する手法がないと思ってますが、もっと良い方法があるよ!という方はブログのコメント欄か、Twitter等で連絡いただけると嬉しいです。)
Confirmation
Confirmationでスロットの内容の確認を簡単に行うことができます。
スロットを指定したい場合はスロットのプロンプトを{}
で囲みます。
「{delivery}
に{iwant}
を希望でよろしいですか?」と入力します。
フルフィルメント
Lambda関数を設定する項目は、Lambdaを作成する前に設定してテストを行うとエラーが起きてしまうので、テスト後に設定します。
フルフィルメントが成功した場合は「サンタさんにお伝えします」、失敗した場合は「エラーが発生しました」と入力します。
応答を閉じる
チャットを終了する時のメッセージを入力します。
設定が終わったら、右下の”インテントを保存”をクリックし、右上のBuildをクリックします。
Lexのテスト
ここで一旦、Lexの流れをテストします。
右上のTestボタンをクリックし、一連の流れを通して確認します。
”検査”ボタンをクリックすることで、JSONの入力/出力の内容を確認できます。
(マネジメントコンソールがダークモードだとちょっと見づらいですね。。)
最後の”応答”のところのJSONをコピーします。(あとでLambda関数を作成する時に参考にします)
私の場合は、こんな形で出力されていました。
{ "messages": [ { "content": "サンタさんにお伝えします。", "contentType": "PlainText" }, { "content": "いい子にして待っててね。", "contentType": "PlainText" } ], "sessionState": { "dialogAction": { "type": "Close" }, "intent": { "name": "present", "slots": { "delivery": { "value": { "originalValue": "12/25", "interpretedValue": "2022-12-25", "resolvedValues": [ "2022-12-25" ] } }, "iwant": { "value": { "originalValue": "くまのぬいぐるみ", "interpretedValue": "くまのぬいぐるみ", "resolvedValues": [ "くまのぬいぐるみ" ] } } }, "state": "Fulfilled", "confirmationState": "Confirmed" }, "sessionAttributes": {}, "originatingRequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }, "interpretations": [ { "nluConfidence": { "score": 1 }, "intent": { "name": "present", "slots": { "delivery": { "value": { "originalValue": "12/25", "interpretedValue": "2022-12-25", "resolvedValues": [ "2022-12-25" ] } }, "iwant": { "value": { "originalValue": "くまのぬいぐるみ", "interpretedValue": "くまのぬいぐるみ", "resolvedValues": [ "くまのぬいぐるみ" ] } } }, "state": "Fulfilled", "confirmationState": "Confirmed" } }, { "intent": { "name": "FallbackIntent", "slots": {} } } ], "requestAttributes": {}, "sessionId": "xxxxxxxxxxxxxxx" }
この中でresolvedValues
の2022-12-25
とくまのぬいぐるみ
をLambdaで取り出してSNSに連携できれば、メールで内容を送れそうだなということがわかります。
フルフィルメントのLambda設定
テストが終わったら詳細オプションを開き、”フルフィルメントにLambda関数を使用”にチェックを入れます。
最後に右上のBuildをもう1度クリックします。
Amazon SNS
Amazon SNSのトピック作成方法は下記ブログをご確認ください。(数クリックで終了します)
作成できたらSNSのARNを控えておきます。
AWS Lambda
LexからSNSに情報を渡してメールを飛ばすLambdaを作成します。
Python3.9で作成しました。
import boto3 def lambda_handler(event, context): topic_arn = "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxxx:lex-to-email" subject = "【サンタさんのプレゼント受付窓口】申し込みのお知らせ" sns = boto3.resource('sns') date = event.get('interpretations',{})[0].get('intent',{}).get('slots',{}).get('delivery',{}).get('value',{}).get('resolvedValues',{})[0] iwant = event.get('interpretations',{})[0].get('intent',{}).get('slots',{}).get('iwant',{}).get('value',{}).get('resolvedValues',{})[0] platform_endpoint = sns.PlatformEndpoint(topic_arn) msg = """ チャットからプレゼントを受け付けました。\n 配達希望日: {date}\n 欲しいもの: {iwant}\n """.format(date=date, iwant=iwant) response = platform_endpoint.publish( Message = msg, Subject = subject ) return { 'sessionState': { 'dialogAction': { 'type': 'Close' }, 'intent': { 'name': 'present', 'state': 'Fulfilled' } } }
topic_arn
のところに、控えたSNSのトピックARNを貼り付けます。
date
とwant
はテスト時にJSONで吐き出した値を抽出しています。
dateの場合は今回でいうと2022-12-25
、wantはくまのぬいぐるみ
です。
最後にreturn
でLambdaからLexに値を返しています。
今回はAmazon Lex V2のドキュメントに書いてある必須項目のsessionState
,dialogAction
,intent
をreturnで返しました。
LexにLambdaを設定
Lambda関数をデプロイできたら、Lexに対象のLambdaを設定します。
場所はボットのサイドメニューから、エイリアス→言語のJapanese(Japan)→エイリアス言語のサポートです。
ソースとバージョンまたはエイリアスを指定して、保存をクリックします。
Amazon Connect
Amazon Lex、AWS Lambda、Amazon SNSと設定できたので、最後はAmazon Connectを設定します。
マネジメントコンソールの問い合わせフローに飛んで、Amazon Lexの部分で作成したボットとエイリアスを指定して、”Amazon Lex ボットを追加”をクリックします。
Amazon Connectコンソールに入り、フローを作成します。(ほぼLexに任せてるのでかなりシンプルです)
”顧客の入力を取得する”ブロックでLexを設定します。
アナウンスはテキスト読み上げで「サンタさんのプレゼント受付窓口です。プレゼントが欲しいと送信してください。」と入力し、追加したLexボットを指定します。
これで、Amazon Connect、Amazon Lex、AWS Lambda、Amazon SNSを連携することができました!
Amazon Connect Chat
こちらは、下の記事で構築手順を載せてますので割愛します。
作成したAmazon Connectのフローを紐づけてもらえれば、チャットで一連の動作の確認が可能です。
最後に
クリスマスイブということで、サンタさんのプレゼント受付のボットを作ってみました!
実際作ってみようと思うと、Lambdaはどう書くのだろうとか、Lexはどう設定したらいいのだろう等、色々考えることがあり勉強になりました。
これからも”何か作ってみよう”の気持ちを忘れずに、色々試していきたいと思います。
いよいよ、明日はAmazon Connect Advent Calendar 2022の最終日です!(あっという間ですね)
ギークフィード 西山さんが執筆予定です。ぜひ楽しみにしてください!
ではまた!コンサルティング部の洲崎でした。